package com.hydra.cron.server.quartz;


import com.alibaba.fastjson.JSONObject;
import com.hydra.cron.common.utils.ObjectUtil;
import com.hydra.cron.server.model.CronTask;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.util.List;

/**
 * hdyraCron Created by ZhengGong on 15/12/7.
 * PackageName com.hydra.cron.server.quartz
 * Description 定时器管理
 */
public class QuartzManager {

    private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();
    private static String DEFAULT_GROUP = "DEFAULT_GROUP";


    /**
     * 添加任务 并执行
     *
     * @param jobName        任务名
     * @param cls            执行类
     * @param cronExpression cron时间
     */
    public static void addJob(String jobName, Class<? extends Job> cls, String cronExpression, CronTask cronTask) throws SchedulerException {
        Scheduler sched = gSchedulerFactory.getScheduler();

        if (ObjectUtil.isNull(cronTask)) {
            throw new SchedulerException("cronTask is null");
        }

        JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, DEFAULT_GROUP).usingJobData("cronTask", JSONObject.toJSONString(cronTask)).build();// 任务名，任务组，任务执行类

        // 触发器
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)).forJob(jobDetail).withIdentity(buildTrigger(jobName), DEFAULT_GROUP).build();
        sched.scheduleJob(jobDetail, cronTrigger);
        // 启动
        if (!sched.isShutdown()) {
            sched.start();
        }
    }


    /**
     * 更新任务时间
     *
     * @param jobName        任务名
     * @param cronExpression cron时间
     */
    public static void modifyJobTime(String jobName, String cronExpression, CronTask cronTask) throws SchedulerException {
        Scheduler sched = gSchedulerFactory.getScheduler();
        CronTrigger trigger = (CronTrigger) sched.getTrigger(TriggerKey.triggerKey(buildTrigger(jobName), DEFAULT_GROUP));
        if (trigger == null) {
            return;
        }
        String oldTime = trigger.getCronExpression();
        if (!oldTime.equalsIgnoreCase(cronExpression)) {
            JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, DEFAULT_GROUP));
            Class<? extends Job> objJobClass = jobDetail.getJobClass();
            removeJob(jobName);
            addJob(jobName, objJobClass, cronExpression, cronTask);
        }

    }


    /**
     * 移除job任务
     *
     * @param jobName 任务名
     */
    public static void removeJob(String jobName) throws SchedulerException {
        Scheduler sched = gSchedulerFactory.getScheduler();
        sched.pauseJob(JobKey.jobKey(jobName, DEFAULT_GROUP));// 停止触发器
        sched.unscheduleJob(TriggerKey.triggerKey(buildTrigger(jobName), DEFAULT_GROUP));// 移除触发器
        sched.deleteJob(JobKey.jobKey(jobName, DEFAULT_GROUP));// 删除任务
    }


    /**
     * 开启所有任务
     */
    public static void startJobs() throws SchedulerException {
        Scheduler sched = gSchedulerFactory.getScheduler();
        sched.start();
    }


    /**
     * 关闭所有任务
     */
    public static void shutdownJobs() throws SchedulerException {
        Scheduler sched = gSchedulerFactory.getScheduler();
        if (!sched.isShutdown()) {
            sched.shutdown();
        }
    }


    public static List<JobExecutionContext> getAllJobs() throws SchedulerException {
        return gSchedulerFactory.getScheduler().getCurrentlyExecutingJobs();
    }

    private static String buildTrigger(String jobName) {
        return jobName + "TriggerName";
    }
}
